#include "Graphics.h"
#include "Extra Structs.h"

Graphics::Graphics()
	: m_pD3DDevice(NULL)
	, m_hWnd(NULL)
{
	for(int i = 0;i < g_numTextures;++i)
	{
		m_stpTextureBuffer[i].lpTexture = NULL;
	}
}

Graphics::~Graphics()
{
	//m_pD3DFont->Release();

	if (NULL != m_pD3DDevice)
	{

		m_pD3DDevice->Release(); 
		// it may be important later on for the
		// device's release function to be called last
	}
}

bool Graphics::Initialize(HWND hWnd)
{
	m_hWnd = hWnd;
	if ( ! ::GetClientRect ( m_hWnd, &m_rClientRect ) )
	{
		throw "GetClientRect() failed";
	}
	if(!InitDevice())	
		return false;
	if(!InitFont())	
		return false;
	if(!InitTextures())
		return false;
	if(!m_clCharacterLight.Init(m_pD3DDevice,0))
		return false;
	if(!Cursor::Access()->Init(hWnd,m_rClientRect))
		return false;

	return true;
}

bool Graphics::InitDevice()
{
	IDirect3D9* pD3DObject = NULL;
	pD3DObject = Direct3DCreate9(D3D_SDK_VERSION);			// create the d3dobject

	::GetClientRect(m_hWnd, &m_rClientRect);

	D3DCAPS9 D3DCaps;
	HR(pD3DObject->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &D3DCaps));

	// determine what type of vertex processing to use
	DWORD dwBehaviorFlags = 0;

	if(D3DCaps.VertexProcessingCaps != 0)	
	{dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;}
	else	{dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;}	

	//set up present parameters
	m_D3DParams.hDeviceWindow			= m_hWnd;
	m_D3DParams.Windowed				= true;
	m_D3DParams.AutoDepthStencilFormat	= D3DFMT_D24S8;
	m_D3DParams.EnableAutoDepthStencil	= TRUE;
	m_D3DParams.BackBufferCount			= 1;
	m_D3DParams.BackBufferFormat		= D3DFMT_X8R8G8B8;
	m_D3DParams.BackBufferWidth			= SCREEN_WIDTH;
	m_D3DParams.BackBufferHeight		= SCREEN_HEIGHT;
	m_D3DParams.SwapEffect				= D3DSWAPEFFECT_DISCARD;
	m_D3DParams.PresentationInterval	= D3DPRESENT_INTERVAL_IMMEDIATE;
	m_D3DParams.Flags					= D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
	m_D3DParams.MultiSampleQuality		= 0;
	m_D3DParams.MultiSampleType			= D3DMULTISAMPLE_NONE;

	// setup the d3ddevice using the d3dobject and present parameters
	HR(pD3DObject->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd, 
		dwBehaviorFlags, &m_D3DParams, &m_pD3DDevice));

	D3DXCreateSprite(m_pD3DDevice, &m_pSpriteDevice);

	if(m_pD3DDevice == NULL)
		return false;

	pD3DObject->Release();
	return true;
}

bool Graphics::InitFont()
{	
	////Top Left
	m_DebugFontScreenPosition.left		= (long)(10);
	m_DebugFontScreenPosition.right		= (long)(m_DebugFontScreenPosition.left + 100);
	m_DebugFontScreenPosition.top		= (long)(10);
	m_DebugFontScreenPosition.bottom	= (long)(m_DebugFontScreenPosition.top + 50);


	HR(D3DXCreateFont(m_pD3DDevice, 24, 0, NULL, 0, false,
		DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY,
		DEFAULT_PITCH | FF_DONTCARE, TEXT("Times New Roman"),
		&m_pD3DFont));

	if(m_pD3DFont == NULL)
		return false;

	m_DebugTextBuffer << "Initializing...";

	return true;
}

bool Graphics::InitTextures()
{
	m_cszTextureNameBuffer[0] = "Resources/Bunny.png";
	

	for(int i = 0; i < g_numTextures; i++)
	{
		D3DXCreateTextureFromFileEx(m_pD3DDevice, m_cszTextureNameBuffer[i], 0, 0, 0, 0, 
			D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT,
			D3DX_DEFAULT, D3DCOLOR_XRGB(150, 150, 150),
			&m_stpTextureBuffer[i].imgInfo, 0, &m_stpTextureBuffer[i].lpTexture);

		if(m_stpTextureBuffer[i].lpTexture == NULL)
			return false;
	}

	return true;
}

void Graphics::Draw()
{
	//Checks to make sure the screen was cleared
	HR ( m_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0, 0, 0 ), 1.0f,0 ) );

	//Sets up the drawing area for draw text
	RECT TextRect;
	GetClientRect(m_hWnd, &TextRect);

	//Begins the overall scene
	m_pD3DDevice->BeginScene( );

	m_pSpriteDevice->Begin(D3DXSPRITE_ALPHABLEND);

	//Ends the sprite event
	m_pSpriteDevice->End();
	
	RenderObjects();
	RenderText();

	//Ends the sprite scene
	m_pD3DDevice->EndScene( );

	//Presents everything onto the screen
	m_pD3DDevice->Present( NULL, NULL, NULL, NULL );
}

void Graphics::RenderText()
{
	//Draws the FPS count
	m_pD3DFont->DrawTextA(NULL,m_DebugTextBuffer.str().c_str(),
		m_DebugTextBuffer.str().size(), &m_DebugFontScreenPosition,
		DT_LEFT | DT_NOCLIP, D3DCOLOR_ARGB(255, 255, 255, 255));
	m_DebugTextBuffer.str("");
	m_DebugTextBuffer.clear();
}

void Graphics::RenderObjects()
{
	
}